// -*-mode:c++; coding:utf-8-*-

#ifndef _STRINGABLE_HPP_
#define _STRINGABLE_HPP_

// 标志一个类是否定义有用于输出的to_string函数
class stringable_tag_type {};
// 	// typedef stringable_tag stringable_tag;

// 	typedef char * any_string_type;
// 	any_string_type to_string() const;

namespace detail 
{
	template<typename T, typename tag>
	struct stringable_helper;
	
	template<typename T>
	struct stringable_helper<T, typename T::stringable_tag>
	{
		template <typename string_type>
		static inline
		string_type to_string(const T &obj) {
			return obj.to_string ();
		}
	};
} // namespace detail

// template<typename ostream, typename T>
// inline
// ostream &operator<<(ostream &out, const T &obj)
// {
// 	return out << detail::stringable_helper<T, typename T::stringable_tag>::to_string(obj);
// }

#include <string>

class stringable {
public:
	virtual
	~stringable () {}
	
	virtual
	std::string to_string () const = 0;
};

template <typename ostream>
inline
ostream &operator<< (ostream &out, const stringable &obj) {
	out << obj.to_string ();
	return out;
}

#endif	// _STRINGABLE_HPP_
